package com.tengxing.e1.FactoryTest;

import static com.serenegiant.utils.ThreadPool.queueEvent;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.speech.tts.TextToSpeech;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Size;
import android.view.OrientationEventListener;
import android.view.PixelCopy;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.maiarstar.e101.protocol.cerebellum.api.exception.ProtocolException;
import com.maiarstar.e101.protocol.cerebellum.api.model.DLLInfo;
import com.maiarstar.e101.protocol.cerebellum.api.model.HOTInfo;
import com.maiarstar.e101.protocol.cerebellum.api.model.LEDInfo;
import com.maiarstar.e101.protocol.cerebellum.api.model.MTQInfo;
import com.maiarstar.e101.protocol.cerebellum.api.model.PPTInfo;
import com.maiarstar.e101.protocol.cerebellum.api.model.SADAInfo;
import com.maiarstar.e101.protocol.cerebellum.api.module.ICerebellumProtocolGetter;
import com.maiarstar.e101.protocol.cerebellum.api.module.ICerebellumProtocolSetter;
import com.maiarstar.e101.protocol.cerebellum.sdk.CerebellumProtocolSdkManager;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.UVCCamera;
import com.serenegiant.utils.HandlerThreadHandler;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;

public class Stress_Test_Activity extends AppCompatActivity {
    private static final String TAG = "Stress_Test_Activity";
    private CerebellumProtocolSdkManager cerebellumProtocolSdkManager;
    SharedPreferences sharedPreferences;
    SharedPreferences.Editor editor;
    ProgressBar pB_Stress_Progress;
    Button btn_Stress_Pass, btn_Stress_Fail, btn_Stress_Start_Stop;
    TextView eT_Stress_Screen_Refresh_Delay, tV_Total_Run, tV_Stress_Test_Status,
            tV_Stress_Total_Cyc_Cnt, eT_Stress_Total_Cyc_Cnt,
            eT_Stress_MTQ_Parm1, eT_Stress_MTQ_Parm2, eT_Stress_MTQ_Parm3, eT_Stress_MTQ_Cyc_Cnt, eT_Stress_MTQ_Delay,
            eT_Stress_DLL_Parm1, eT_Stress_DLL_Parm2, eT_Stress_DLL_Parm3, eT_Stress_DLL_Parm4,
            eT_Stress_DLL_Parm5, eT_Stress_DLL_Parm6, eT_Stress_DLL_Parm7, eT_Stress_DLL_Parm8,
            tV_Stress_DLL_info, eT_Stress_DLL_Cyc_Cnt, eT_Stress_DLL_Delay,
            tV_Stress_IMU_info, eT_Stress_IMU_Cyc_Cnt, eT_Stress_IMU_Delay,
            tV_Stress_SUS_info, eT_Stress_SUS_Cyc_Cnt, eT_Stress_SUS_Delay,
            eT_Stress_PPT_Parm1, eT_Stress_PPT_Parm2, eT_Stress_PPT_Parm3, eT_Stress_PPT_Parm4,
            eT_Stress_PPT_Cyc_Cnt, eT_Stress_PPT_Delay,
            tV_Stress_TMP_Info, eT_Stress_TMP_Cyc_Cnt, eT_Stress_TMP_Delay,
            tV_Stress_SADA, eT_Stress_SADA_Parm1, eT_Stress_SADA_Parm2, eT_Stress_SADA_Cyc_Cnt, eT_Stress_SADA_Delay, tV_Stress_Test_SADA_IsOnLine,
            eT_Stress_MIPI_Cam_Cyc_Cnt, eT_Stress_MIPI_Cam_Delay;

    private static Handler handler_refresh_status_task;
    private static Runnable run_refresh_status_task;

    boolean stress_Test_break = false;
    Thread stress_test_thread;
    int mtq_parm1, mtq_parm2, mtq_parm3, mtq_cyc_cnt, mtq_delay, mtq_num = 3,
        dll_parm1, dll_parm2, dll_parm3, dll_parm4, dll_parm5, dll_parm6, dll_parm7, dll_parm8, dll_cyc_cnt, dll_delay, dll_num = 3,
        imu_cyc_cnt, imu_delay,
        sus_cyc_cnt, sus_delay,
        ppt_parm1, ppt_parm2, ppt_parm3, ppt_parm4, ppt_cyc_cnt, ppt_delay,
        tmp_cyc_cnt, tmp_delay,
        sada_parm1, sada_parm2, sada_cyc_cnt, sada_delay, sada_isOnline,
        mipi_Cam_Cyc_Cnt, mipi_Cam_Delay;

    int total_runtime = 0, now_runtime = 0, stress_Total_Cyc_Cnt = 0, stress_Now_Cyc_Cnt = 0;

    double imu_x, imu_y, imu_z, temp_val, hum_val;

    boolean stress_Test_isRun = false;

    Integer mtq_pwr, mtq_direction, dll_dr_now, dll_rpm_now, lux_val;
    String dll_str, imu_str, sus_str, tmp_str, test_status_str = "压力测试状态(已停止):";

    //对比判断
    int[] sus_comp = new int[4];
    double[] temp_comp = new double[4];
    double[] hum_comp = new double[4];
    TextToSpeech textToSpeech;

    //=====Mipi Camera Start
    private TextureView mTextureView;
    private Handler mChildHandler;
    private CameraManager mCameraManager;
    private String mCurrentCameraId;
    private Size mCurrentSelectSize;
    private ImageReader mImageReader;
    private CameraDevice.StateCallback mCameraDeviceStateCallback;
    private CameraDevice mCameraDevice;
    private Surface mSurface;
    private CaptureRequest.Builder mCaptureRequest;
    private CameraCaptureSession.StateCallback mCameraCaptureSessionStateCallback;
    private CameraCaptureSession.CaptureCallback mCameraCaptureSessionCaptureCallback;
    private CameraCaptureSession mCameraCaptureSession;
    private Integer cam_facing = CameraCharacteristics.LENS_FACING_BACK;
    //=====Mipi Camera End
    //=====USB Dev Start
    private static final boolean DEBUG = false;	// TODO set false when production
    private UsbManager usbManager;
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
    private static final int USB_PERMISSION_REQUEST_CODE = 1001;
    //=====USB Dev End
    //=====USB Camera Start
    private final Object mSync = new Object();
    // for accessing USB and USB camera
    private USBMonitor mUSBMonitor;
    private UVCCamera mUVCCamera;
    private SurfaceView mUVCCameraView;
    // for open&start / stop&close camera preview
    //private ImageButton mCameraButton;
    private Surface mPreviewSurface;
    private boolean isActive, isPreview;
    private Handler mWorkerHandler;
    private long mWorkerThreadID = -1;
    //=====USB Camera End


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_stress_test);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        sharedPreferences = getSharedPreferences("Test_Result", MODE_PRIVATE);
        initCerebellumManager();
        TTS_Init();
        Init_FindId();
        Factory_Camera_Stress_Init();
        Factory_USB_Camera_Stress_Init();
        Refresh_Status_Task_Init();
        Factory_Stress_BTN();

        //TTS_Speak("初始化完成");
    }
    //=====USB Camera Start
    @Override
    protected void onStart() {
        super.onStart();
        synchronized (mSync) {
            if (mUSBMonitor != null) {
                mUSBMonitor.register();

            }
            if (mUVCCamera != null){
                mUVCCamera.startPreview();
            }
        }
    }

    @Override
    protected void onStop() {
        synchronized (mSync) {
            if (mUSBMonitor != null) {
                mUSBMonitor.unregister();
            }
            if (mUVCCamera != null) {
                mUVCCamera.stopPreview();
            }
        }
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        synchronized (mSync) {
            isActive = isPreview = false;
            if (mUVCCamera != null) {
                mUVCCamera.destroy();
                mUVCCamera = null;
            }
            if (mUSBMonitor != null) {
                mUSBMonitor.destroy();
                mUSBMonitor = null;
            }
        }
        mUVCCameraView = null;
        super.onDestroy();
    }
    void Factory_USB_Camera_Stress_Init(){

        usbManager = (UsbManager) getSystemService(USB_SERVICE);
        requestStoragePermission();
        Get_Camera_Permission();
        Get_USB_Permission();
        Get_USB_Devices();
        //===== USB Camera Start =====
        if(Check_Camera_Permission()){//如果有相机权限就启动相机
            if (mWorkerHandler == null) {
                mWorkerHandler = HandlerThreadHandler.createHandler(TAG);
                mWorkerThreadID = mWorkerHandler.getLooper().getThread().getId();
            }

            mUVCCameraView = (SurfaceView)findViewById(R.id.surfaceView_Stress_USB_Cam);
            mUVCCameraView.getHolder().addCallback(mSurfaceViewCallback);
            mUSBMonitor = new USBMonitor(this, mOnDeviceConnectListener);//serenegiant usb camera*/
        }

        //===== USB Camera End =====
    }
    private final SurfaceHolder.Callback mSurfaceViewCallback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(final SurfaceHolder holder) {
            if (DEBUG) Log.v(TAG, "surfaceCreated:");
        }

        @Override
        public void surfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height) {
            if ((width == 0) || (height == 0)) return;
            if (DEBUG) Log.v(TAG, "surfaceChanged:");
            mPreviewSurface = holder.getSurface();
            synchronized (mSync) {
                if (isActive && !isPreview && (mUVCCamera != null)) {
                    mUVCCamera.setPreviewDisplay(mPreviewSurface);
                    mUVCCamera.startPreview();
                    isPreview = true;
                }
            }
        }

        @Override
        public void surfaceDestroyed(final SurfaceHolder holder) {
            if (DEBUG) Log.v(TAG, "surfaceDestroyed:");
            synchronized (mSync) {
                if (mUVCCamera != null) {
                    mUVCCamera.stopPreview();
                }
                isPreview = false;
            }
            mPreviewSurface = null;
        }
    };

    private final USBMonitor.OnDeviceConnectListener mOnDeviceConnectListener = new USBMonitor.OnDeviceConnectListener() {
        @Override
        public void onAttach(final UsbDevice device) {
            if (DEBUG) {
                Log.v(TAG, "onAttach: dev="+ device.getDeviceId() + " pd_name:" + device.getProductName());
                Toast.makeText(Stress_Test_Activity.this, "USB_DEVICE_ATTACHED\ndev="+ device.getDeviceId() + " pd_name:" + device.getProductName(), Toast.LENGTH_SHORT).show();
            }
            mUSBMonitor.requestPermission(device);
        }

        @Override
        public void onConnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock, final boolean createNew) {

            if (DEBUG) Log.v(TAG, "onConnect:" + device.getProductName());
            if(device.getProductName() == null){
                if (DEBUG) Log.d(TAG, "onConnect: no usb dev");
                return;
            }
            if(device.getProductName().contains("Camera") || device.getProductName().contains("camera")){
                if (DEBUG) Log.d(TAG, "onConnect: usb cam dev find.");
            }else{
                if (DEBUG) Log.d(TAG, "onConnect: no usb cam dev.");
                return;
            }
            synchronized (mSync) {
                if (DEBUG) Log.d(TAG, "mUVCCamera: mSync");
                if (mUVCCamera != null) {
                    if (DEBUG) Log.d(TAG, "mUVCCamera: not null");
                    mUVCCamera.destroy();
                }
                isActive = isPreview = false;
            }
            queueEvent(new Runnable() {
                @Override
                public void run() {
                    if (DEBUG) Log.d(TAG, "queueEvent:" + device.getProductName());
                    synchronized (mSync) {
                        final UVCCamera camera = new UVCCamera();
                        camera.open(ctrlBlock);
                        if (DEBUG) Log.d(TAG, "supportedSize:" + camera.getSupportedSize());
                        try {
                            camera.setPreviewSize(UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, UVCCamera.FRAME_FORMAT_MJPEG);
                        } catch (final IllegalArgumentException e) {
                            try {
                                // fallback to YUV mode
                                camera.setPreviewSize(UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, UVCCamera.DEFAULT_PREVIEW_MODE);
                            } catch (final IllegalArgumentException e1) {
                                camera.destroy();
                                return;
                            }
                        }
                        mPreviewSurface = mUVCCameraView.getHolder().getSurface();
                        if (mPreviewSurface != null) {
                            isActive = true;
                            camera.setPreviewDisplay(mPreviewSurface);
                            camera.startPreview();
                            isPreview = true;
                        }
                        synchronized (mSync) {
                            mUVCCamera = camera;
                        }
                    }
                }
            });
        }

        @Override
        public void onDisconnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock) {
            if (DEBUG) Log.v(TAG, "onDisconnect:");
            // XXX you should check whether the comming device equal to camera device that currently using
            queueEvent(new Runnable() {
                @Override
                public void run() {
                    synchronized (mSync) {
                        if (mUVCCamera != null) {
                            mUVCCamera.close();
                            if (mPreviewSurface != null) {
                                mPreviewSurface.release();
                                mPreviewSurface = null;
                            }
                            isActive = isPreview = false;
                        }
                    }
                }
            });
        }

        @Override
        public void onDettach(final UsbDevice device) {
            if (DEBUG) Log.v(TAG, "onDettach:");
            Toast.makeText(Stress_Test_Activity.this, "USB_DEVICE_DETACHED", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCancel(final UsbDevice device) {
        }
    };

    //=====USB Camera End
    //=====USB Cam & MIPI Cam Picture Save Start=====
    private static final int REQUEST_WRITE_STORAGE = 1;

    private void requestStoragePermission() {
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    REQUEST_WRITE_STORAGE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_WRITE_STORAGE && grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 权限已授予
        }
    }
    public void Capture_MIPI_Cam_TV(TextureView textureView) {
        Bitmap bitmap = textureView.getBitmap();
        String path= Environment.getExternalStorageDirectory()+"/DCIM/E1_Cam_Stress/";
        File mImageFile=new File(path);
        if(!mImageFile.exists()){
            mImageFile.mkdir();     //如果路径不存在就建一个
        }
        String timeStamp=new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String fileName="IMG_MIPI_Cam_Stress_"+timeStamp+".jpg";
        saveBitmapToStorage(path, fileName, bitmap);
    }
    public void Capture_USB_Cam_SV(SurfaceView surfaceView) {
        //Bitmap bitmap = Bitmap.createBitmap(2560, 1440, Bitmap.Config.ARGB_8888);
        Bitmap bitmap = Bitmap.createBitmap(surfaceView.getWidth(), surfaceView.getHeight(), Bitmap.Config.ARGB_8888);
        String path= Environment.getExternalStorageDirectory()+"/DCIM/E1_Cam_Stress/";
        File mImageFile=new File(path);
        if(!mImageFile.exists()){
            mImageFile.mkdir();     //如果路径不存在就建一个
        }
        String timeStamp=new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String fileName="IMG_USB_Cam_Stress_"+timeStamp+".jpg";

        PixelCopy.request(surfaceView, bitmap, copyResult -> {
            if (copyResult == PixelCopy.SUCCESS) {
                saveBitmapToStorage(path, fileName, bitmap);
            }
        }, new Handler(Looper.getMainLooper()));
    }

    private void saveBitmapToStorage(String path, String fileName, Bitmap bitmap) {
        File imageFile = new File(path, fileName);

        try (FileOutputStream fos = new FileOutputStream(imageFile)) {
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            Toast.makeText(this, "图片已保存至：" + imageFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            Log.e(TAG, "saveBitmapToStorage:"+e);
        }
    }
    //=====USB Cam & MIPI Cam Picture Save End=====

    //=====USB Permission Start
    private final BroadcastReceiver mUsbPermissionActionReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice usbDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        //user choose YES for your previously popup window asking for grant perssion for this usb device
                        if(null != usbDevice){
                            //afterGetUsbPermission(usbDevice);
                        }
                    }
                    else {
                        //user choose NO for your previously popup window asking for grant perssion for this usb device
                        Toast.makeText(context, String.valueOf("Permission denied for device" + usbDevice), Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    };
    boolean Check_Camera_Permission(){
        return ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
    }

    void Get_Camera_Permission(){
        final int REQUEST_CAMERA_CODE = 100;
        if ( !Check_Camera_Permission() ) {
            //申请相机权限
            requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_CODE);
        }
    }
    void Get_USB_Permission(){
        IntentFilter intentFilter = new IntentFilter(ACTION_USB_PERMISSION);
        //if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        registerReceiver(mUsbPermissionActionReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED);
        //}
        PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, USB_PERMISSION_REQUEST_CODE, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE);
        //here do emulation to ask all connected usb device for permission
        for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
            //add some conditional check if necessary
            //if(isWeCaredUsbDevice(usbDevice)){
            if(DEBUG) Log.d(TAG, usbDevice.getDeviceId()+" permission: "+ usbManager.hasPermission(usbDevice));
            if(usbManager.hasPermission(usbDevice)){
                //if has already got permission, just goto connect it
                //that means: user has choose yes for your previously popup window asking for grant perssion for this usb device
                //and also choose option: not ask again
                //afterGetUsbPermission(usbDevice);
                if(DEBUG) Log.d(TAG, usbDevice.getDeviceId()+" have usb permission");
            }else{
                //this line will let android popup window, ask user whether to allow this app to have permission to operate this usb device

                if(DEBUG) Log.d(TAG, usbDevice.getDeviceId()+" request usb permission");
                usbManager.requestPermission(usbDevice, mPermissionIntent);

            }
            //}
        }
    }
    void Get_USB_Devices(){
        String usb_dev_str="USB Device List:\n";

        for(UsbDevice usbDevice : usbManager.getDeviceList().values()){
            usb_dev_str = usb_dev_str.concat("Dev:" + usbDevice.getDeviceName() +
                    "  Dev_id:"+ usbDevice.getDeviceId() +
                    "  Class:" + usbDevice.getDeviceClass() +
                    " Sub_Class:" + usbDevice.getDeviceSubclass() +


                    "\nPd_Name:"+ usbDevice.getProductName()+
                    "  MF_Name:" + usbDevice.getManufacturerName()+
                    "\nDev_Pt:" + usbDevice.getDeviceProtocol() +
                    "  SN:" + usbDevice.getSerialNumber()+
                    "  Ver:" + usbDevice.getVersion()+
                    "  VID:" + usbDevice.getVendorId()+
                    "  Pd_ID:" + usbDevice.getProductId()+
                    "\n\n");
        }
        Toast.makeText(Stress_Test_Activity.this, usb_dev_str, Toast.LENGTH_LONG).show();

    }
    //===== USB Permission End


    private void Init_FindId(){
        pB_Stress_Progress = findViewById(R.id.pB_Stress_Progress);
        eT_Stress_Screen_Refresh_Delay = findViewById(R.id.eT_Stress_Screen_Refresh_Delay);

        eT_Stress_MTQ_Parm1 = findViewById(R.id.eT_Stress_MTQ_Parm1);
        eT_Stress_MTQ_Parm2 = findViewById(R.id.eT_Stress_MTQ_Parm2);
        eT_Stress_MTQ_Parm3 = findViewById(R.id.eT_Stress_MTQ_Parm3);
        eT_Stress_MTQ_Cyc_Cnt = findViewById(R.id.eT_Stress_MTQ_Cyc_Cnt);
        eT_Stress_MTQ_Delay = findViewById(R.id.eT_Stress_MTQ_Delay);

        eT_Stress_DLL_Parm1 = findViewById(R.id.eT_Stress_DLL_Parm1);
        eT_Stress_DLL_Parm2 = findViewById(R.id.eT_Stress_DLL_Parm2);
        eT_Stress_DLL_Parm3 = findViewById(R.id.eT_Stress_DLL_Parm3);
        eT_Stress_DLL_Parm4 = findViewById(R.id.eT_Stress_DLL_Parm4);
        eT_Stress_DLL_Parm5 = findViewById(R.id.eT_Stress_DLL_Parm5);
        eT_Stress_DLL_Parm6 = findViewById(R.id.eT_Stress_DLL_Parm6);
        eT_Stress_DLL_Parm7 = findViewById(R.id.eT_Stress_DLL_Parm7);
        eT_Stress_DLL_Parm8 = findViewById(R.id.eT_Stress_DLL_Parm8);
        eT_Stress_DLL_Cyc_Cnt = findViewById(R.id.eT_Stress_DLL_Cyc_Cnt);
        eT_Stress_DLL_Delay = findViewById(R.id.eT_Stress_DLL_Delay);
        tV_Stress_DLL_info = findViewById(R.id.tV_Stress_DLL_info);

        tV_Stress_IMU_info = findViewById(R.id.tV_Stress_IMU_info);
        eT_Stress_IMU_Cyc_Cnt = findViewById(R.id.eT_Stress_IMU_Cyc_Cnt);
        eT_Stress_IMU_Delay = findViewById(R.id.eT_Stress_IMU_Delay);

        tV_Stress_SUS_info = findViewById(R.id.tV_Stress_SUS_info);
        eT_Stress_SUS_Cyc_Cnt = findViewById(R.id.eT_Stress_SUS_Cyc_Cnt);
        eT_Stress_SUS_Delay = findViewById(R.id.eT_Stress_SUS_Delay);

        eT_Stress_PPT_Parm1 = findViewById(R.id.eT_Stress_PPT_Parm1);
        eT_Stress_PPT_Parm2 = findViewById(R.id.eT_Stress_PPT_Parm2);
        eT_Stress_PPT_Parm3 = findViewById(R.id.eT_Stress_PPT_Parm3);
        eT_Stress_PPT_Parm4 = findViewById(R.id.eT_Stress_PPT_Parm4);
        eT_Stress_PPT_Cyc_Cnt = findViewById(R.id.eT_Stress_PPT_Cyc_Cnt);
        eT_Stress_PPT_Delay = findViewById(R.id.eT_Stress_PPT_Delay);

        tV_Stress_TMP_Info = findViewById(R.id.tV_Stress_TMP_Info);
        eT_Stress_TMP_Cyc_Cnt = findViewById(R.id.eT_Stress_TMP_Cyc_Cnt);
        eT_Stress_TMP_Delay = findViewById(R.id.eT_Stress_TMP_Delay);

        tV_Stress_SADA = findViewById(R.id.tV_Stress_SADA);
        eT_Stress_SADA_Parm1 = findViewById(R.id.eT_Stress_SADA_Parm1);
        eT_Stress_SADA_Parm2 = findViewById(R.id.eT_Stress_SADA_Parm2);
        eT_Stress_SADA_Cyc_Cnt = findViewById(R.id.eT_Stress_SADA_Cyc_Cnt);
        eT_Stress_SADA_Delay = findViewById(R.id.eT_Stress_SADA_Delay);
        tV_Stress_Test_SADA_IsOnLine = findViewById(R.id.tV_Stress_Test_SADA_IsOnLine);

        tV_Total_Run = findViewById(R.id.tV_Total_Run);
        tV_Stress_Test_Status = findViewById(R.id.tV_Stress_Test_Status);
        tV_Stress_Total_Cyc_Cnt = findViewById(R.id.tV_Stress_Total_Cyc_Cnt);
        eT_Stress_Total_Cyc_Cnt = findViewById(R.id.eT_Stress_Total_Cyc_Cnt);

        eT_Stress_MIPI_Cam_Cyc_Cnt = findViewById(R.id.eT_Stress_MIPI_Cam_Cyc_Cnt);
        eT_Stress_MIPI_Cam_Delay = findViewById(R.id.eT_Stress_MIPI_Cam_Delay);
    }
    private void Refresh_Parm_Cycle(){
        total_runtime = 0;
        try {
            stress_Total_Cyc_Cnt = Integer.parseInt(eT_Stress_Total_Cyc_Cnt.getText().toString());
        }catch (Exception e){
            Log.e(TAG, "Refresh_Parm:Total_Cyc_Cnt:"+e);
        }
        try{
            mtq_parm1 = Integer.parseInt(eT_Stress_MTQ_Parm1.getText().toString());
            mtq_parm2 = Integer.parseInt(eT_Stress_MTQ_Parm2.getText().toString());
            mtq_parm3 = Integer.parseInt(eT_Stress_MTQ_Parm3.getText().toString());
            mtq_cyc_cnt = Integer.parseInt(eT_Stress_MTQ_Cyc_Cnt.getText().toString());
            mtq_delay = Integer.parseInt(eT_Stress_MTQ_Delay.getText().toString());
            total_runtime = total_runtime + mtq_cyc_cnt*(mtq_num*(mtq_parm1+mtq_parm2+mtq_parm3)+mtq_delay);
        }catch (Exception e){
            Log.e(TAG, "Refresh_Parm:mtq:"+e);
        }

        try{
            dll_parm1 = Integer.parseInt(eT_Stress_DLL_Parm1.getText().toString());
            dll_parm2 = Integer.parseInt(eT_Stress_DLL_Parm2.getText().toString());
            dll_parm3 = Integer.parseInt(eT_Stress_DLL_Parm3.getText().toString());
            dll_parm4 = Integer.parseInt(eT_Stress_DLL_Parm4.getText().toString());
            dll_parm5 = Integer.parseInt(eT_Stress_DLL_Parm5.getText().toString());
            dll_parm6 = Integer.parseInt(eT_Stress_DLL_Parm6.getText().toString());
            dll_parm7 = Integer.parseInt(eT_Stress_DLL_Parm7.getText().toString());
            dll_parm8 = Integer.parseInt(eT_Stress_DLL_Parm8.getText().toString());
            dll_cyc_cnt = Integer.parseInt(eT_Stress_DLL_Cyc_Cnt.getText().toString());
            dll_delay = Integer.parseInt(eT_Stress_DLL_Delay.getText().toString());
            total_runtime = total_runtime + dll_cyc_cnt*( dll_parm2+dll_parm4+dll_parm6+dll_parm8+dll_delay*2 );
        }catch (Exception e){
            Log.e(TAG, "Refresh_Parm:dll:"+e);
        }

        try{
            imu_cyc_cnt = Integer.parseInt(eT_Stress_IMU_Cyc_Cnt.getText().toString());
            imu_delay = Integer.parseInt(eT_Stress_IMU_Delay.getText().toString());
            total_runtime = total_runtime + imu_cyc_cnt*imu_delay;
        }catch (Exception e){
            Log.e(TAG, "Refresh_Parm:imu:"+e);
        }

        try{
            sus_cyc_cnt = Integer.parseInt(eT_Stress_SUS_Cyc_Cnt.getText().toString());
            sus_delay = Integer.parseInt(eT_Stress_SUS_Delay.getText().toString());
            total_runtime = total_runtime + sus_cyc_cnt*sus_delay;
        }catch (Exception e){
            Log.e(TAG, "Refresh_Parm:sus:"+e);
        }

        try{
            ppt_parm1 = Integer.parseInt(eT_Stress_PPT_Parm1.getText().toString());
            ppt_parm2 = Integer.parseInt(eT_Stress_PPT_Parm2.getText().toString());
            ppt_parm3 = Integer.parseInt(eT_Stress_PPT_Parm3.getText().toString());
            ppt_parm4 = Integer.parseInt(eT_Stress_PPT_Parm4.getText().toString());
            ppt_cyc_cnt = Integer.parseInt(eT_Stress_PPT_Cyc_Cnt.getText().toString());
            ppt_delay = Integer.parseInt(eT_Stress_PPT_Delay.getText().toString());
            total_runtime = total_runtime + ppt_cyc_cnt*(ppt_parm2+ppt_parm4+ppt_delay);
        }catch (Exception e){
            Log.e(TAG, "Refresh_Parm:sus:"+e);
        }

        try{
            tmp_cyc_cnt = Integer.parseInt(eT_Stress_TMP_Cyc_Cnt.getText().toString());
            tmp_delay = Integer.parseInt(eT_Stress_TMP_Delay.getText().toString());
            total_runtime = total_runtime + tmp_cyc_cnt*tmp_delay;
        }catch (Exception e){
            Log.e(TAG, "Refresh_Parm:tmp:"+e);
        }

        sada_isOnline = GetSADAOnLine(1);
        if(sada_isOnline==0x31){
            try{
                sada_parm1 = Integer.parseInt(eT_Stress_SADA_Parm1.getText().toString());
                sada_parm2 = Integer.parseInt(eT_Stress_SADA_Parm2.getText().toString());
                sada_cyc_cnt = Integer.parseInt(eT_Stress_SADA_Cyc_Cnt.getText().toString());
                sada_delay = Integer.parseInt(eT_Stress_SADA_Delay.getText().toString());
                total_runtime = total_runtime + sada_cyc_cnt*2*sada_delay;
            }catch (Exception e){
                Log.e(TAG, "Refresh_Parm:sada:"+e);
                tV_Stress_Test_SADA_IsOnLine.setText("SADA在线状态：未知或错误");
            }
            tV_Stress_Test_SADA_IsOnLine.setText("SADA在线状态：在线");
            tV_Stress_SADA.setVisibility(View.VISIBLE);
            eT_Stress_SADA_Parm1.setVisibility(View.VISIBLE);
            eT_Stress_SADA_Parm2.setVisibility(View.VISIBLE);
            eT_Stress_SADA_Cyc_Cnt.setVisibility(View.VISIBLE);
            eT_Stress_SADA_Delay.setVisibility(View.VISIBLE);
        }else{
            tV_Stress_Test_SADA_IsOnLine.setText("SADA在线状态：离线");
            tV_Stress_SADA.setVisibility(View.INVISIBLE);
            eT_Stress_SADA_Parm1.setVisibility(View.INVISIBLE);
            eT_Stress_SADA_Parm2.setVisibility(View.INVISIBLE);
            eT_Stress_SADA_Cyc_Cnt.setVisibility(View.INVISIBLE);
            eT_Stress_SADA_Delay.setVisibility(View.INVISIBLE);
        }

        try{
            mipi_Cam_Cyc_Cnt = Integer.parseInt(eT_Stress_MIPI_Cam_Cyc_Cnt.getText().toString());
            mipi_Cam_Delay = Integer.parseInt(eT_Stress_MIPI_Cam_Delay.getText().toString());
            total_runtime = total_runtime + mipi_Cam_Cyc_Cnt*(2*mipi_Cam_Delay);
        }catch (Exception e){
            Log.e(TAG, "Refresh_Parm:mipi_cam:"+e);
        }

        //Refresh_DLL_Status();
        tV_Stress_DLL_info.setText(dll_str);
        tV_Stress_IMU_info.setText(imu_str);
        tV_Stress_SUS_info.setText(sus_str);
        tV_Stress_TMP_Info.setText(tmp_str);

        total_runtime = total_runtime * stress_Total_Cyc_Cnt;
        tV_Stress_Test_Status.setText(test_status_str);
        pB_Stress_Progress.setMax(total_runtime);
        pB_Stress_Progress.setProgress(now_runtime);
        tV_Stress_Total_Cyc_Cnt.setText("总循环次数:" + (stress_Now_Cyc_Cnt+1) + "/");
        tV_Total_Run.setText("压力测试时长(s):" + (double)now_runtime/1000 + "/" + (double)total_runtime/1000);

    }

    private void Refresh_Status_Task_Init(){
        handler_refresh_status_task = new Handler(Looper.getMainLooper());//新建任务
        run_refresh_status_task = new Runnable() {
            @Override
            public void run() {
                handler_refresh_status_task.postDelayed(this, Get_Screen_Refresh_Delay());
                Refresh_Parm_Cycle();
                //Log.d(TAG, "Refresh_Status_Cycle:in");
            }
        };
        handler_refresh_status_task.post(run_refresh_status_task);//启动任务
        //Log.d(TAG, "Refresh_Status_Cycle:out");
    }



    private void Stress_Test_Thread_SleepTick(int sleep_ms){
        try {
            Thread.sleep(sleep_ms);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }


    private void Stress_Test_Thread(){
        stress_test_thread = new Thread(){
            @Override
            public void run(){
                SetLED(1,200);
                SetLED(2,200);
                SetLED(3,200);
                WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                WriteStressTestLog("stress_test_log_all.txt","===== ===== ===== 压力测试开始 ===== ===== =====\n\n");
                WriteStressTestLogDate("stress_test_log_DLL.txt");//记录时间
                WriteStressTestLog("stress_test_log_DLL.txt","===== ===== ===== 压力测试开始 ===== ===== =====\n\n");
                WriteStressTestLogDate("stress_test_log_IMU.txt");//记录时间
                WriteStressTestLog("stress_test_log_IMU.txt","===== ===== ===== 压力测试开始 ===== ===== =====\n\n");
                WriteStressTestLogDate("stress_test_log_SUS.txt");//记录时间
                WriteStressTestLog("stress_test_log_SUS.txt","===== ===== ===== 压力测试开始 ===== ===== =====\n\n");
                WriteStressTestLogDate("stress_test_log_TMP.txt");//记录时间
                WriteStressTestLog("stress_test_log_TMP.txt","===== ===== ===== 压力测试开始 ===== ===== =====\n\n");
                for(int i=0; i<stress_Total_Cyc_Cnt; i++) {
                    stress_Now_Cyc_Cnt = i;
                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== ===== 压力测试第"+(i+1)+"轮开始 ===== =====\n\n");

                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== 磁力矩器测试开始 ====="+"\n");
                    for(int j = 0; j < mtq_cyc_cnt; j++) { //mtq
                        if (stress_Test_break) break;
                        TTS_Speak("正在运行磁力矩器");
                        //Log.d(TAG, "Stress_Test_Task_Cycle:mtq_cyc_cnt" + j);
                        for(int k = 0; k < mtq_num; k++) {
                            if (stress_Test_break) break;
                            //Log.d(TAG, "Stress_Test_Task_Cycle:mtq_num" + k);
                            test_status_str = "\t压力测试状态(正在进行)：磁力矩器"+(k+1)+",第"+(j+1)+"轮";
                            WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                            WriteStressTestLog("stress_test_log_all.txt",test_status_str+"\n");
                            SetMTQ(k + 1, 1, 1);
                            Stress_Test_Thread_SleepTick(mtq_parm1);
                            now_runtime = now_runtime + mtq_parm1;
                            SetMTQ(k + 1, 1, 0);
                            if (stress_Test_break) break;
                            Stress_Test_Thread_SleepTick(mtq_parm2);
                            now_runtime = now_runtime + mtq_parm2;
                            SetMTQ(k + 1, 0, 1);
                            if (stress_Test_break) break;
                            Stress_Test_Thread_SleepTick(mtq_parm3);
                            now_runtime = now_runtime + mtq_parm3;
                        }
                        Stress_Test_Thread_SleepTick(mtq_delay);
                        now_runtime = now_runtime + mtq_delay;
                        WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                        WriteStressTestLog("stress_test_log_all.txt","===== 磁力矩器测试结束 =====\n\n");
                    }

                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== 动量轮测试开始 =====\n");
                    WriteStressTestLogDate("stress_test_log_DLL.txt");//记录时间
                    WriteStressTestLog("stress_test_log_DLL.txt","===== ===== 动量轮压力测试总第"+(i+1)+"轮 ===== =====\n\n");
                    for(int j = 0; j < dll_cyc_cnt; j++) {//dll
                        if (stress_Test_break) break;
                        TTS_Speak("正在运行动量轮");
                        //Log.d(TAG, "Stress_Test_Task_Cycle:dll_cyc_cnt" + j);
                        test_status_str = "\t压力测试状态(正在进行)：动量轮 第"+(j+1)+"轮";
                        WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                        WriteStressTestLog("stress_test_log_all.txt",test_status_str+"\n");
                        WriteStressTestLogDate("stress_test_log_DLL.txt");//记录时间
                        WriteStressTestLog("stress_test_log_DLL.txt",test_status_str+"\n");
                        for(int k = 0; k < dll_num; k++) {
                            if (stress_Test_break) break;
                            SetDLL(k + 1, 1, dll_parm1);
                        }
                        WriteStressTestLog("stress_test_log_all.txt","设定转速：+"+dll_parm1+"  实际转速：");
                        WriteStressTestLog("stress_test_log_DLL.txt","设定转速：+"+dll_parm1+"  实际转速：");

                        Stress_Test_Thread_SleepTick(dll_parm2);
                        now_runtime = now_runtime + dll_parm2;
                        for(int k = 0; k < dll_num; k++) {
                            if (stress_Test_break) break;
                            GetDLL(k+1);
                            WriteStressTestLog("stress_test_log_all.txt","   +"+dll_rpm_now);
                            WriteStressTestLog("stress_test_log_DLL.txt","   +"+dll_rpm_now);
                            if((dll_rpm_now == null) || (dll_rpm_now < dll_parm1-500) || (dll_rpm_now > dll_parm1+500)){
                                WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                                WriteStressTestLog("stress_test_log_err.txt","\tDLL"+(k+1)+":转速异常，设定:+"+dll_parm1+"，实际:+"+dll_rpm_now+"\n");
                            }
                            SetDLL(k+1, 1, dll_parm3);
                        }
                        WriteStressTestLog("stress_test_log_all.txt","\n设定转速：+"+dll_parm3+"  实际转速：");
                        WriteStressTestLog("stress_test_log_DLL.txt","\n设定转速：+"+dll_parm3+"  实际转速：");
                        Stress_Test_Thread_SleepTick(dll_parm4);
                        now_runtime = now_runtime + dll_parm4;
                        for(int k = 0; k < dll_num; k++) {
                            if (stress_Test_break) break;
                            GetDLL(k+1);
                            WriteStressTestLog("stress_test_log_all.txt","   +"+dll_rpm_now);
                            WriteStressTestLog("stress_test_log_DLL.txt","   +"+dll_rpm_now);
                            if((dll_rpm_now == null) || (dll_rpm_now < dll_parm3-500) || (dll_rpm_now > dll_parm3+500)){
                                WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                                WriteStressTestLog("stress_test_log_err.txt","\tDLL"+(k+1)+":转速异常，设定:+"+dll_parm3+"，实际:+"+dll_rpm_now+"\n");
                            }
                            SetDLL(k+1, 1, 0);
                        }
                        Stress_Test_Thread_SleepTick(dll_delay);
                        now_runtime = now_runtime + dll_delay;
                        for(int k = 0; k < dll_num; k++) {
                            if (stress_Test_break) break;
                            SetDLL(k+1, 0, dll_parm5);
                        }
                        WriteStressTestLog("stress_test_log_all.txt","\n设定转速：-"+dll_parm5+"  实际转速：");
                        WriteStressTestLog("stress_test_log_DLL.txt","\n设定转速：-"+dll_parm5+"  实际转速：");
                        Stress_Test_Thread_SleepTick(dll_parm6);
                        now_runtime = now_runtime + dll_parm6;
                        for(int k = 0; k < dll_num; k++) {
                            if (stress_Test_break) break;
                            GetDLL(k+1);
                            WriteStressTestLog("stress_test_log_all.txt","   -"+dll_rpm_now);
                            WriteStressTestLog("stress_test_log_DLL.txt","   -"+dll_rpm_now);
                            if((dll_rpm_now == null) || (dll_rpm_now < dll_parm5-500) || (dll_rpm_now > dll_parm5+500)){
                                WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                                WriteStressTestLog("stress_test_log_err.txt","\tDLL"+(k+1)+":转速异常，设定:-"+dll_parm5+"，实际:-"+dll_rpm_now+"\n");
                            }
                            SetDLL(k+1, 0, dll_parm7);
                        }
                        WriteStressTestLog("stress_test_log_all.txt","\n设定转速：-"+dll_parm7+"  实际转速：");
                        WriteStressTestLog("stress_test_log_DLL.txt","\n设定转速：-"+dll_parm7+"  实际转速：");
                        Stress_Test_Thread_SleepTick(dll_parm8);
                        now_runtime = now_runtime + dll_parm8;
                        for(int k = 0; k < dll_num; k++) {
                            if (stress_Test_break) break;
                            GetDLL(k+1);
                            WriteStressTestLog("stress_test_log_all.txt","   -"+dll_rpm_now);
                            WriteStressTestLog("stress_test_log_DLL.txt","   -"+dll_rpm_now);
                            if((dll_rpm_now == null) || (dll_rpm_now < dll_parm7-500) || (dll_rpm_now > dll_parm7+500)){
                                WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                                WriteStressTestLog("stress_test_log_err.txt","\tDLL"+(k+1)+":转速异常，设定:-"+dll_parm7+"，实际:-"+dll_rpm_now+"\n");
                            }
                            SetDLL(k+1, 0, 0);
                        }
                        Stress_Test_Thread_SleepTick(dll_delay);
                        now_runtime = now_runtime + dll_delay;
                        WriteStressTestLog("stress_test_log_all.txt","\n");
                        WriteStressTestLog("stress_test_log_DLL.txt","\n");
                    }
                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== 动量轮测试结束 =====\n\n");

                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== IMU测试开始 =====\n");
                    WriteStressTestLogDate("stress_test_log_IMU.txt");//记录时间
                    WriteStressTestLog("stress_test_log_IMU.txt","===== ===== IMU压力测试总第"+(i+1)+"轮 ===== =====\n\n");
                    for(int j = 0; j < imu_cyc_cnt; j++) {//imu
                        if (stress_Test_break) break;
                        TTS_Speak("正在读取惯性测量单元");
                        test_status_str = "\t压力测试状态(正在进行)：IMU 第"+(j+1)+"轮";
                        //Log.d(TAG, "Stress_Test_Task_Cycle:imu_cyc_cnt" + j);
                        WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                        WriteStressTestLog("stress_test_log_all.txt",test_status_str+"\n");
                        WriteStressTestLogDate("stress_test_log_IMU.txt");//记录时间
                        WriteStressTestLog("stress_test_log_IMU.txt",test_status_str+"\n");
                        Refresh_IMU_Status();
                        Stress_Test_Thread_SleepTick(imu_delay);
                        now_runtime = now_runtime + imu_delay;
                    }
                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== IMU测试结束 =====\n\n");

                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== 太敏测试开始 =====\n");
                    WriteStressTestLogDate("stress_test_log_SUS.txt");//记录时间
                    WriteStressTestLog("stress_test_log_SUS.txt","===== ===== 太敏压力测试总第"+(i+1)+"轮 ===== =====\n\n");
                    for(int j = 0; j < sus_cyc_cnt; j++) {//sus
                        TTS_Speak("正在读取太敏 ");
                        if (stress_Test_break) break;
                        test_status_str = "\t压力测试状态(正在进行)：太敏 第"+(j+1)+"轮";
                        //Log.d(TAG, "Stress_Test_Task_Cycle:sus_cyc_cnt" + j);
                        WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                        WriteStressTestLog("stress_test_log_all.txt",test_status_str+"\n");
                        WriteStressTestLogDate("stress_test_log_SUS.txt");//记录时间
                        WriteStressTestLog("stress_test_log_SUS.txt",test_status_str+"\n");
                        Refresh_SUS_Status();
                        Stress_Test_Thread_SleepTick(sus_delay);
                        now_runtime = now_runtime + sus_delay;
                    }
                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== 太敏测试结束 =====\n\n");

                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== 电推测试开始 =====\n");
                    for(int j = 0; j < ppt_cyc_cnt; j++) {//ppt
                        if (stress_Test_break) break;
                        TTS_Speak("正在运行电力推进器");
                        test_status_str = "\t压力测试状态(正在进行)：电推 第"+(j+1)+"轮";
                        //Log.d(TAG, "Stress_Test_Task_Cycle:ppt_cyc_cnt" + j);
                        WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                        WriteStressTestLog("stress_test_log_all.txt",test_status_str+"\n");
                        for(int k = 1; k<5; k++){
                            SetPPT(k, ppt_parm1);
                        }
                        Stress_Test_Thread_SleepTick(ppt_parm2);
                        now_runtime = now_runtime + ppt_parm2;
                        for(int k = 1; k<5; k++){
                            SetPPT(k, ppt_parm3);
                        }
                        Stress_Test_Thread_SleepTick(ppt_parm4);
                        now_runtime = now_runtime + ppt_parm4;
                        for(int k = 1; k<5; k++){
                            SetPPT(k, 0);
                        }
                        Stress_Test_Thread_SleepTick(ppt_delay);
                        now_runtime = now_runtime + ppt_delay;
                    }
                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== 电推测试结束 =====\n\n");

                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== 温度、加热测试开始 =====\n");
                    WriteStressTestLogDate("stress_test_log_TMP.txt");//记录时间
                    WriteStressTestLog("stress_test_log_TMP.txt","===== ===== 温度、加热压力测试总第"+(i+1)+"轮 ===== =====\n\n");
                    SetHOT(1,1);
                    TTS_Speak("正在运行加热片与读取温度");
                    for(int j = 0; j < tmp_cyc_cnt; j++) {//tmp & hot
                        tmp_str = "";
                        if (stress_Test_break) break;
                        test_status_str = "\t压力测试状态(正在进行)：温度、加热 第"+(j+1)+"轮";
                        //Log.d(TAG, "Stress_Test_Task_Cycle:tmp_cyc_cnt" + j);
                        WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                        WriteStressTestLog("stress_test_log_all.txt",test_status_str+"\n");
                        WriteStressTestLogDate("stress_test_log_TMP.txt");//记录时间
                        WriteStressTestLog("stress_test_log_TMP.txt",test_status_str+"\n");
                        for(int k=0; k<4; k++){
                            GetTMP(k+1);
                            tmp_str = tmp_str.concat((k+1)+":"+temp_val+"℃"+hum_val+"%    ");
                            temp_comp[k] = temp_val;
                            hum_comp[k] = hum_val;
                            if(temp_val>50 || temp_val<-10){
                                WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                                WriteStressTestLog("stress_test_log_err.txt","\tTMP"+(k+1)+"超限(-10~50):"+temp_val+"℃\n");
                            }
                        }
                        if(temp_comp[0]==temp_comp[1] || temp_comp[1]==temp_comp[2] || temp_comp[2]==temp_comp[3] || temp_comp[3]==temp_comp[0]){
                            WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                            WriteStressTestLog("stress_test_log_err.txt","\tTMP有值相等:");
                            for(int k=0; k<4; k++){
                                WriteStressTestLog("stress_test_log_err.txt",temp_comp[k]+"℃ ");
                            }
                            WriteStressTestLog("stress_test_log_err.txt","\n");
                        }
                        if(hum_comp[0]==hum_comp[1] || hum_comp[1]==hum_comp[2] || hum_comp[2]==hum_comp[3] || hum_comp[3]==hum_comp[0]){
                            WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                            WriteStressTestLog("stress_test_log_err.txt","\tHUM有值相等:");
                            for(int k=0; k<4; k++){
                                WriteStressTestLog("stress_test_log_err.txt",hum_comp[k]+"% ");
                            }
                            WriteStressTestLog("stress_test_log_err.txt","\n");
                        }

                        Stress_Test_Thread_SleepTick(tmp_delay);
                        now_runtime = now_runtime + tmp_delay;
                        WriteStressTestLog("stress_test_log_all.txt",tmp_str+"\n");
                        WriteStressTestLog("stress_test_log_TMP.txt",tmp_str+"\n");
                    }
                    SetHOT(1,0);
                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== 温度、加热测试结束 =====\n\n");

                    if(sada_isOnline==0x31){
                        WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                        WriteStressTestLog("stress_test_log_all.txt","===== SADA测试开始 =====\n");
                        for(int j = 0; j < sada_cyc_cnt; j++) {//sada
                            if (stress_Test_break) break;
                            TTS_Speak("正在运行太阳翼 ");
                            test_status_str = "\t压力测试状态(正在进行)：SADA 第"+(j+1)+"轮";
                            //Log.d(TAG, "Stress_Test_Task_Cycle:sada_cyc_cnt" + j);
                            WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                            WriteStressTestLog("stress_test_log_all.txt",test_status_str+"\n");
                            SetSADA(1, sada_parm1);
                            SetSADA(2, sada_parm1);
                            Stress_Test_Thread_SleepTick(sada_delay);
                            now_runtime = now_runtime + sada_delay;
                            SetSADA(1, sada_parm2);
                            SetSADA(2, sada_parm2);
                            Stress_Test_Thread_SleepTick(sada_delay);
                            now_runtime = now_runtime + sada_delay;
                        }
                        SetSADA(1, 90);
                        SetSADA(2, 90);
                        WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                        WriteStressTestLog("stress_test_log_all.txt","===== SADA测试结束 =====\n\n");
                    }else{
                        WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                        WriteStressTestLog("stress_test_log_all.txt","===== SADA不在位 =====\n\n");
                    }


                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== MIPI/USB相机测试开始 =====\n");
                    for(int j = 0; j < mipi_Cam_Cyc_Cnt; j++){
                        if (stress_Test_break) break;
                        TTS_Speak("正在测试相机");
                        test_status_str = "\t压力测试状态(正在进行)：Cam 第"+(j+1)+"轮";
                        //Log.d(TAG, "Stress_Test_Task_Cycle:mipi_Cam_Cyc_Cnt" + j);
                        WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                        WriteStressTestLog("stress_test_log_all.txt",test_status_str+"\n");
                        Switch_Camera();
                        /*//前摄
                        cam_facing = CameraCharacteristics.LENS_FACING_FRONT;
                        initSelectCamera();
                        try{
                            mCameraManager.openCamera(mCurrentCameraId, mCameraDeviceStateCallback, mChildHandler);
                        }catch (Exception e){
                            test_status_str = "\t前摄打开失败";
                            WriteStressTestLog("stress_test_log_all.txt",test_status_str+"\n");
                        }
                        takePicture();*/
                        Stress_Test_Thread_SleepTick(mipi_Cam_Delay);
                        now_runtime = now_runtime + mipi_Cam_Delay;


                        /*//后摄
                        cam_facing = CameraCharacteristics.LENS_FACING_BACK;
                        initSelectCamera();
                        try{
                            mCameraManager.openCamera(mCurrentCameraId, mCameraDeviceStateCallback, mChildHandler);
                        }catch (Exception e){
                            test_status_str = "\t后摄打开失败";
                            WriteStressTestLog("stress_test_log_all.txt",test_status_str+"\n");
                        }
                        takePicture();*/
                        Capture_MIPI_Cam_TV(mTextureView);
                        Capture_USB_Cam_SV(mUVCCameraView);
                        Stress_Test_Thread_SleepTick(mipi_Cam_Delay);
                        now_runtime = now_runtime + mipi_Cam_Delay;

                    }
                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== MIPI/USB相机测试结束 =====\n\n");

                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== ===== 压力测试第"+(i+1)+"轮结束 ===== =====\n\n");

                }


                for(int i = 1; i<4; i++){
                    SetMTQ(i, 0, 1);
                    SetDLL(i, 1, 0);
                }
                for(int i = 1; i<5; i++){
                    SetPPT(i, 0);
                }
                SetLED(1,1000);
                SetLED(2,0);
                SetLED(3,0);
                now_runtime = total_runtime;
                stress_Test_break = false;
                stress_Test_isRun = false;
                btn_Stress_Start_Stop.setText("开始压力测试");
                test_status_str = "压力测试状态(已停止)：";
                WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                WriteStressTestLog("stress_test_log_all.txt","===== ===== ===== 压力测试结束 ===== ===== =====\n\n\n\n");
                WriteStressTestLogDate("stress_test_log_DLL.txt");//记录时间
                WriteStressTestLog("stress_test_log_DLL.txt","===== ===== ===== 压力测试结束 ===== ===== =====\n\n\n\n");
                WriteStressTestLogDate("stress_test_log_IMU.txt");//记录时间
                WriteStressTestLog("stress_test_log_IMU.txt","===== ===== ===== 压力测试结束 ===== ===== =====\n\n\n\n");
                WriteStressTestLogDate("stress_test_log_SUS.txt");//记录时间
                WriteStressTestLog("stress_test_log_SUS.txt","===== ===== ===== 压力测试结束 ===== ===== =====\n\n\n\n");
                WriteStressTestLogDate("stress_test_log_TMP.txt");//记录时间
                WriteStressTestLog("stress_test_log_TMP.txt","===== ===== ===== 压力测试结束 ===== ===== =====\n\n\n\n");
                btn_Stress_Start_Stop.setClickable(true);
            }
        };
    }

    private int Get_Screen_Refresh_Delay(){
        try{
            return Integer.parseInt(eT_Stress_Screen_Refresh_Delay.getText().toString());
        }catch (Exception e){
            Toast.makeText(Stress_Test_Activity.this, "Err:"+e, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Get_Screen_Refresh_Delay"+e);
        }
        return 1000;
    }

    private void Factory_Stress_BTN() {
        btn_Stress_Start_Stop = findViewById(R.id.btn_Stress_Start_Stop);
        btn_Stress_Start_Stop.setText("开始压力测试");
        btn_Stress_Start_Stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(stress_Test_isRun){
                    //handler_stress_test_task.removeCallbacks(run_stress_test_task);//杀掉任务
                    stress_Test_break = true;
                    btn_Stress_Start_Stop.setText("压力测试停止中…");
                    test_status_str = "压力测试状态(正在停止)：";
                    btn_Stress_Start_Stop.setClickable(false);
                    WriteStressTestLog("stress_test_log_all.txt","\n\n");
                    WriteStressTestLogDate("stress_test_log_all.txt");//记录时间
                    WriteStressTestLog("stress_test_log_all.txt","===== ===== ===== 手动停止测试 ===== ===== =====\n\n");
                }else{
                    //handler_stress_test_task.post(run_stress_test_task);//启动任务

                    Stress_Test_Thread();
                    stress_test_thread.start();

                    btn_Stress_Start_Stop.setText("停止压力测试");
                    test_status_str = "压力测试状态(正在进行)：";
                    now_runtime = 0;
                    stress_Test_isRun = true;
                }
                //stress_Test_isRun = !stress_Test_isRun;
                //Toast.makeText(Stress_Test_Activity.this, "btn:"+now_runtime+"/"+total_runtime, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private boolean SetMTQ(Integer num, Integer pwr, Integer direction) throws ProtocolException {
        try {
            MTQInfo mtqInfo = new MTQInfo();
            mtqInfo.setOrder(num);
            mtqInfo.setPower(pwr);
            mtqInfo.setDirection(direction);
            ICerebellumProtocolSetter setter = this.cerebellumProtocolSdkManager.getCerebellumProtocolSetter();
            return setter.setMTQInfo(mtqInfo);
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }

    private boolean GetMTQ(Integer num) throws ProtocolException {
        try {
            ICerebellumProtocolGetter getter = this.cerebellumProtocolSdkManager.getCerebellumProtocolGetter();
            mtq_pwr = getter.getMTQInfo(num).getPower();
            mtq_direction = getter.getMTQInfo(num).getDirection();
            return true;
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }

    private boolean SetDLL(int num, int direction, int rpm) throws ProtocolException {
        try {
            DLLInfo dllInfo = new DLLInfo();
            dllInfo.setOrder(num);
            dllInfo.setPower(direction);
            dllInfo.setRev(rpm);
            ICerebellumProtocolSetter setter = this.cerebellumProtocolSdkManager.getCerebellumProtocolSetter();
            return setter.setDLLInfo(dllInfo);
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }

    private boolean GetDLL(int num) throws ProtocolException {
        try {
            ICerebellumProtocolGetter getter = this.cerebellumProtocolSdkManager.getCerebellumProtocolGetter();
            getter.getDLLInfo(num);
            dll_dr_now = getter.getDLLInfo(num).getPower();
            dll_rpm_now = getter.getDLLInfo(num).getRev();
            return true;
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }
    private void Refresh_DLL_Status(){
        dll_str = "";
        for(int i=1; i<4; i++){
            if(GetDLL(i)){
                dll_str = dll_str.concat("   DLL" + i + ":" + dll_dr_now + "," + dll_rpm_now);
            }else{
                dll_str = dll_str.concat("   DLL" + i + "获取失败");
            }
        }
    }

    private void Refresh_IMU_Status(){
        imu_str = "";
        if(GetIMU(1)){
            imu_str = imu_str.concat("Gyro:" + imu_x + ", "+ imu_y + ", " + imu_z);
            if((imu_x==imu_y && imu_y==imu_z && imu_x==imu_z) ||
                    (imu_x>1000) || (imu_x<-1000) || (imu_y>1000) || (imu_y<-1000) || (imu_z>1000) || (imu_z<-1000)){
                WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                WriteStressTestLog("stress_test_log_err.txt","\tIMU:  Gyro异常:"+imu_x+","+imu_y+","+imu_z+"\n");
            }
        }else{
            imu_str = imu_str.concat("Gyro获取失败");
            WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
            WriteStressTestLog("stress_test_log_err.txt","\tIMU:  Gyro获取失败\n");
        }
        if(GetIMU(2)){
            imu_str = imu_str.concat("   Accel:" + imu_x + ", "+ imu_y + ", " + imu_z);
            if((imu_x==imu_y && imu_y==imu_z && imu_x==imu_z) ||
                    (imu_x>1000) || (imu_x<-1000) || (imu_y>1000) || (imu_y<-1000) || (imu_z>1000) || (imu_z<-1000)){
                WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                WriteStressTestLog("stress_test_log_err.txt","\tIMU:  Acc异常:"+imu_x+","+imu_y+","+imu_z+"\n");
            }
        }else{
            imu_str = imu_str.concat("   Accel获取失败");
            WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
            WriteStressTestLog("stress_test_log_err.txt","\tIMU:  Accel获取失败\n");
        }
        if(GetIMU(3)){
            imu_str = imu_str.concat("   Mag:" + imu_x + ", "+ imu_y + ", " + imu_z);
            if((imu_x==imu_y && imu_y==imu_z && imu_x==imu_z) ||
                    (imu_x>1000) || (imu_x<-1000) || (imu_y>1000) || (imu_y<-1000) || (imu_z>1000) || (imu_z<-1000)){
                WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                WriteStressTestLog("stress_test_log_err.txt","\tIMU:  Mag异常:"+imu_x+","+imu_y+","+imu_z+"\n");
            }
        }else{
            imu_str = imu_str.concat("   Mag获取失败");
            WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
            WriteStressTestLog("stress_test_log_err.txt","\tIMU:  Mag获取失败\n");
        }
        WriteStressTestLog("stress_test_log_all.txt",imu_str+"\n");
        WriteStressTestLog("stress_test_log_IMU.txt",imu_str+"\n");
    }
    private boolean GetIMU(int num) throws ProtocolException {
        try {
            imu_x = 0; imu_y = 0; imu_z = 0;
            ICerebellumProtocolGetter getter = this.cerebellumProtocolSdkManager.getCerebellumProtocolGetter();
            //getter.getIMUInfo(num);
            imu_x = getter.getIMUInfo(num).getX();
            imu_y = getter.getIMUInfo(num).getY();
            imu_z = getter.getIMUInfo(num).getZ();
            return true;
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }

    private void Refresh_SUS_Status(){
        sus_str = "";
        for(int i=0; i<4; i++){
            lux_val = -1;
            if(GetSUS(i+1)){
                sus_str = sus_str.concat(lux_val+"，");
            }else{
                sus_str = sus_str.concat("失败，");

            }
            sus_comp[i] = lux_val;
        }
        for(int i=0; i<4; i++){
            if(i<=2){
                if(sus_comp[i] == sus_comp[i+1] ){
                    //sus_str = sus_str.concat("ERROR有值相等 ");
                    WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                    WriteStressTestLog("stress_test_log_err.txt","\tSUS有值相等:SUS"+i+"=SUS:"+(i+1)+"-"+sus_comp[i]+"\n");
                }
            }
            if(sus_comp[3] == sus_comp[0] ){
                WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                WriteStressTestLog("stress_test_log_err.txt","\tSUS有值相等:SUS4=SUS1-"+sus_comp[3]+"\n");
            }
            if(sus_comp[i]==-1){
                WriteStressTestLogDate("stress_test_log_err.txt");//记录时间
                WriteStressTestLog("stress_test_log_err.txt","\tSUS"+i+"获取失败"+"\n");
            }

        }
        WriteStressTestLog("stress_test_log_all.txt",sus_str+"\n");
        WriteStressTestLog("stress_test_log_SUS.txt",sus_str+"\n");
    }

    private boolean GetSUS(int num) throws ProtocolException {
        try {
            ICerebellumProtocolGetter getter = this.cerebellumProtocolSdkManager.getCerebellumProtocolGetter();
            lux_val = getter.getSUSInfo(num).getSense();
            return true;
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }

    private boolean SetPPT(int num, int dutyPersent) throws ProtocolException {
        try {
            PPTInfo pptInfo = new PPTInfo();
            pptInfo.setOrder(num);
            pptInfo.setPower(dutyPersent);
            ICerebellumProtocolSetter setter = this.cerebellumProtocolSdkManager.getCerebellumProtocolSetter();
            setter.setPPTInfo(pptInfo);
            return true;
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }

    private boolean GetTMP(int num) throws ProtocolException {
        try {
            ICerebellumProtocolGetter getter = this.cerebellumProtocolSdkManager.getCerebellumProtocolGetter();
            temp_val = getter.getTMPInfo(num).getTemp();
            hum_val = getter.getHUMInfo(num).getHumidity();
            return true;
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }

    private boolean SetHOT(int num, int pwr) throws ProtocolException {
        try {
            HOTInfo hotInfo = new HOTInfo();
            hotInfo.setOrder(num);
            hotInfo.setPower(pwr);
            ICerebellumProtocolSetter setter = this.cerebellumProtocolSdkManager.getCerebellumProtocolSetter();
            return setter.setHOTInfo(hotInfo);
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }

    private int GetSADAOnLine(int num) throws ProtocolException {
        try {
            ICerebellumProtocolGetter getter = this.cerebellumProtocolSdkManager.getCerebellumProtocolGetter();
            return getter.getSADAInfo(num).getReign();
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return -1;
    }
    private boolean SetSADA(int num, int degree) throws ProtocolException {
        try {
            SADAInfo sadaInfo = new SADAInfo();
            sadaInfo.setOrder(num);
            sadaInfo.setCurrent_angle(degree);
            ICerebellumProtocolSetter setter = this.cerebellumProtocolSdkManager.getCerebellumProtocolSetter();
            return setter.setSADAInfo(sadaInfo);
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }

    private void initCerebellumManager() {
        CerebellumProtocolSdkManager sdkProtocolManager = new CerebellumProtocolSdkManager(this);
        CerebellumProtocolSdkManager.SdkParams sdkParams = CerebellumProtocolSdkManager.getDeafultSdkParams();
        try {
            sdkProtocolManager.init(sdkParams);
        } catch (ProtocolException e) {
            Log.w(TAG, e.getMessage());
        }
        this.cerebellumProtocolSdkManager = sdkProtocolManager;
    }

    private boolean SetLED(int num, int cyc_time) throws ProtocolException {
        try {
            LEDInfo ledInfo = new LEDInfo();
            ledInfo.setOrder(num);
            ledInfo.setPower(cyc_time);
            ICerebellumProtocolSetter setter = this.cerebellumProtocolSdkManager.getCerebellumProtocolSetter();
            return setter.setLEDInfo(ledInfo);
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return false;
    }
    private void WriteStressTestLogDate(String log_file_name){
        try {
            OutputStream os = openFileOutput(log_file_name, Context.MODE_APPEND);
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
            Date date = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("<YYYY-MM-dd HH:mm:ss>");
            bw.write(dateFormat.format(date));
            bw.write('\n');
            bw.close();
            os.close();
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
            throw new RuntimeException(e);
        }
    }
    private void WriteStressTestLog(String log_file_name, String log_str){
        try {
            OutputStream os = openFileOutput(log_file_name, Context.MODE_APPEND);
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
            bw.write(log_str);
            bw.close();
            os.close();
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
            throw new RuntimeException(e);
        }
    }
    private void TTS_Init(){
        textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                try {
                    textToSpeech.setLanguage(Locale.CHINESE);
                }catch (Exception e){
                    Log.e(TAG, "TTS:"+e);
                }
            }
        });
    }
    private void TTS_Speak(String speak_str){
        try {
            textToSpeech.speak(speak_str, TextToSpeech.QUEUE_FLUSH, null, null);
        }catch (Exception e){
            Log.e(TAG, "TTS:"+e);
        }
    }

    //=====Mipi Camera Start
    void Factory_Camera_Stress_Init() {
        mTextureView = findViewById(R.id.textureView_Stress_MIPI_Cam);
        initChildThread();
        initCameraManager();
        initSelectCamera();
        initHandlerMatchingSize();
        initImageReader();
        initTextureViewListener();
        initCameraDeviceStateCallbackListener();
        initCameraCaptureSessionStateCallbackListener();
        initCameraCaptureSessionCaptureCallbackListener();

    }

    private void initChildThread() {
        HandlerThread handlerThread = new HandlerThread("faceCamera");
        handlerThread.start();
        mChildHandler = new Handler(handlerThread.getLooper());

    }

    /**
     * 初始化相机管理
     */
    private void initCameraManager() {
        mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    }


    /**
     * 初始化选择摄像头
     */
    private void initSelectCamera() {
        try {
            String[] cameraIdArray = mCameraManager.getCameraIdList();
            for (String itemId : cameraIdArray) {
                CameraCharacteristics itemCharacteristics = mCameraManager.getCameraCharacteristics(itemId);
                Integer facing = itemCharacteristics.get(CameraCharacteristics.LENS_FACING);
                if (facing == cam_facing) {
                    mCurrentCameraId = itemId;
                    break;
                }
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        if (mCurrentCameraId == null) {
            finish();
            Toast.makeText(this, "找不到摄像头", Toast.LENGTH_SHORT).show();
        }

    }

    /**
     * 初始化计算适合当前屏幕分辨率的拍照分辨率
     * @return
     */
    private void initHandlerMatchingSize() {
        try {
            CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(mCurrentCameraId);
            StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            Size[] sizes = streamConfigurationMap.getOutputSizes(ImageFormat.JPEG);
            DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
            int deviceWidth = displayMetrics.widthPixels;
            int deviceHeigh = displayMetrics.heightPixels;
            Log.e(TAG,"当前屏幕密度宽度="+deviceWidth+"高度="+deviceHeigh);
            for (int j = 1; j < 81; j++) {
                for (int i = 0; i < sizes.length; i++) {
                    Size itemSize = sizes[i];
                    if (itemSize.getHeight() < (deviceWidth + j * 5) && itemSize.getHeight() > (deviceWidth - j * 5)) {
                        if (mCurrentSelectSize != null) { //如果之前已经找到一个匹配的宽度
                            if (Math.abs(deviceHeigh-itemSize.getWidth()) < Math.abs(deviceHeigh - mCurrentSelectSize.getWidth())){ //求绝对值算出最接近设备高度的尺寸
                                mCurrentSelectSize = itemSize;
                                continue;

                            }
                        }else {
                            mCurrentSelectSize = itemSize;
                        }

                    }
                }

            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        Log.e(TAG,"当前预览宽度="+mCurrentSelectSize.getWidth()+"高度="+mCurrentSelectSize.getHeight());
    }

    private void initImageReader() {
        Log.e(TAG,"初始化图片ImageReader的宽="+mCurrentSelectSize.getWidth()+"高="+mCurrentSelectSize.getHeight());
        mImageReader = ImageReader.newInstance(mCurrentSelectSize.getWidth()
                , mCurrentSelectSize.getHeight()
                , ImageFormat.JPEG
                , 1);

        mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader reader) {

                Image image = reader.acquireLatestImage();
                ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer();
                byte[] bytes = new byte[byteBuffer.remaining()];
                byteBuffer.get(bytes);
                /*final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                if (bitmap != null) {
                    //imageView.setImageBitmap(bitmap);
                }*/

                String path= Environment.getExternalStorageDirectory()+"/DCIM/FactoryTest_Camera/";
                File mImageFile=new File(path);
                if(!mImageFile.exists()){
                    mImageFile.mkdir();     //如果路径不存在就建一个
                }
                //文件命名方式：年月日_时分秒
                String timeStamp=new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
                String fileName=path+"IMG_FactoryTest_"+timeStamp+".jpg";
                try {
                    FileOutputStream fos=new FileOutputStream(fileName);
                    fos.write(bytes,0,bytes.length);    //写出图片
                } catch (FileNotFoundException e) {
                    throw new RuntimeException(e);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }


                // 处理完后记得释放资源
                //image.close();

            }
        }, mChildHandler);
    }

    private void initTextureViewListener() {
        mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                openCamera();

            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                return true;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {

            }
        });
    }

    private void initCameraDeviceStateCallbackListener() {
        mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
            @Override
            public void onOpened(@NonNull CameraDevice camera) {
                //相机开启
                mCameraDevice = camera;
                try {
                    SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
                    surfaceTexture.setDefaultBufferSize(mCurrentSelectSize.getWidth(),mCurrentSelectSize.getHeight());
                    mSurface = new Surface(surfaceTexture);
                    mCaptureRequest = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                    mCaptureRequest.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                    mCaptureRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);//自动爆光
                    mCaptureRequest.addTarget(mSurface);
                    mCameraDevice.createCaptureSession(Arrays.asList(mSurface, mImageReader.getSurface()), mCameraCaptureSessionStateCallback, mChildHandler);

                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }

            }

            @Override
            public void onDisconnected(@NonNull CameraDevice camera) {

            }

            @Override
            public void onError(@NonNull CameraDevice camera, int error) {
                finish();
                Toast.makeText(Stress_Test_Activity.this, "相机打开失败", Toast.LENGTH_SHORT).show();
                Log.e(TAG,"CameraDevice.StateCallback onError : 相机异常 error code="+error);

            }
        };
    }

    private void initCameraCaptureSessionStateCallbackListener() {
        mCameraCaptureSessionStateCallback = new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(@NonNull CameraCaptureSession session) {
                mCameraCaptureSession = session;
                startPreview();

            }

            @Override
            public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                finish();
                Toast.makeText(Stress_Test_Activity.this, "相机打开失败", Toast.LENGTH_SHORT).show();
                Log.e(TAG,"CameraCaptureSession.StateCallback onConfigureFailed : CameraCaptureSession会话通道创建失败");

            }
        };
    }

    private void initCameraCaptureSessionCaptureCallbackListener() {
        mCameraCaptureSessionCaptureCallback = new CameraCaptureSession.CaptureCallback() {
            @Override
            public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
                super.onCaptureStarted(session, request, timestamp, frameNumber);
                //获取开始
            }

            @Override
            public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
                super.onCaptureProgressed(session, request, partialResult);
                //获取中
            }

            @Override
            public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                super.onCaptureCompleted(session, request, result);
                //获取结束
            }

            @Override
            public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
                super.onCaptureFailed(session, request, failure);
                //获取失败

                Toast.makeText(Stress_Test_Activity.this, "拍照失败", Toast.LENGTH_SHORT).show();
                Log.e(TAG,"失败报告Reason="+failure.getReason());

            }
        };
    }
    /**
     * 打开摄像头
     */
    @SuppressLint("MissingPermission")
    private void openCamera() {
        try {
            mCameraManager.openCamera(mCurrentCameraId, mCameraDeviceStateCallback, mChildHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }



    /**
     * 开始预览
     */
    private void startPreview(){
        try {
            mCameraCaptureSession.setRepeatingRequest(mCaptureRequest.build(), mCameraCaptureSessionCaptureCallback, mChildHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止预览
     */
    private void stopPreview(){
        try {
            mCameraCaptureSession.stopRepeating();
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    /**
     * 拍照
     */
    private void takePicture(){
        try {
            CaptureRequest.Builder takePictureRequest = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            takePictureRequest.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);//自动对焦
            takePictureRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);//自动爆光
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            int angle = getJpegOrientation(mCameraManager.getCameraCharacteristics(mCurrentCameraId), rotation);
            Log.i(TAG,"照片角度="+angle);
            takePictureRequest.set(CaptureRequest.JPEG_ORIENTATION, angle);
            Surface surface = mImageReader.getSurface();
            takePictureRequest.addTarget(surface);
            CaptureRequest request = takePictureRequest.build();
            mCameraCaptureSession.capture(request, null, mChildHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    /**
     * 官方提供的JPEG图片方向算法
     * @param c
     * @param deviceOrientation
     * @return
     */
    private int getJpegOrientation(CameraCharacteristics c, int deviceOrientation) {
        if (deviceOrientation == OrientationEventListener.ORIENTATION_UNKNOWN){
            return 0;
        }
        int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION);//获取传感器方向

        // Round device orientation to a multiple of 90
        deviceOrientation = (deviceOrientation + 45) / 90 * 90;

        // Reverse device orientation for front-facing cameras
        boolean facingFront = c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT;//判断摄像头面向
        if (facingFront) {
            deviceOrientation = -deviceOrientation;
        }

        // Calculate desired JPEG orientation relative to camera orientation to make
        // the image upright relative to the device orientation
        int jpegOrientation = (sensorOrientation + deviceOrientation + 360) % 360;

        return jpegOrientation;
    }



    private void Switch_Camera(){
        if(cam_facing == CameraCharacteristics.LENS_FACING_BACK){
            cam_facing = CameraCharacteristics.LENS_FACING_FRONT;
        }else{
            cam_facing = CameraCharacteristics.LENS_FACING_BACK;
        }
        initSelectCamera();
        try{
            mCameraManager.openCamera(mCurrentCameraId, mCameraDeviceStateCallback, mChildHandler);
        }catch (Exception e){

        }
    }

    private void Close_Camera(){
        if (mImageReader != null){
            mImageReader.close();
            mImageReader = null;
        }
        if (mCameraCaptureSession != null){
            stopPreview();
            try {
                mCameraCaptureSession.abortCaptures();
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
            mCameraCaptureSession.close();
            mCameraCaptureSession = null;
        }
        if (mCaptureRequest != null){
            mCaptureRequest.removeTarget(mSurface);//注意释放mSurface
            mCaptureRequest = null;
        }
        if (mSurface != null){
            mSurface.release();//注意释放mSurface
            mSurface = null;
        }
        //也可以用onSurfaceTextureDestroyed这种方式释放SurfaceTexture 但是在上面的public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) 回调中你需要返回true或者自己执行 surface.release(); 这步资源释放很重要
        //mTextureView.getSurfaceTextureListener().onSurfaceTextureDestroyed(mTextureView.getSurfaceTexture());
        mCameraDeviceStateCallback = null;
        mCameraCaptureSessionStateCallback = null;
        mCameraCaptureSessionCaptureCallback = null;
        mCameraManager = null;
        if (mCameraDevice != null){
            mCameraDevice.close();
            mCameraDevice = null;
        }
        mCameraManager = null;
        if (mChildHandler != null){
            mChildHandler.removeCallbacksAndMessages(null);
            mChildHandler = null;

        }
    }
    //=====Mipi Camera End

    @Override
    public void onBackPressed() {
        if(stress_Test_isRun){
            Toast.makeText(Stress_Test_Activity.this, "先停止测试再退出！", Toast.LENGTH_SHORT).show();
        }else{
            if (textToSpeech != null) {
                textToSpeech.stop();
                textToSpeech.shutdown();
            }
            Close_Camera();

            Intent intent = new Intent(Stress_Test_Activity.this, MainActivity.class);
            startActivity(intent);
            handler_refresh_status_task.removeCallbacks(run_refresh_status_task);//杀掉任务

            finish();

            super.onBackPressed();
        }
    }
}